#include <cstdio>
#include <algorithm>
#include <cassert>

using namespace std;

typedef unsigned int uint;

template <class T> 
class cartesian_tree
{ 
  public:


  T key;
  uint y;
  uint count;

  cartesian_tree *l, *r;

  cartesian_tree (int _key)
  {
    count = 1;
    key = _key;
    y = ((((uint)rand())<<15) + rand());
    l = NULL;
    r = NULL;
  }

  cartesian_tree (void)
  {
    count = 1;
    key = 0;
    y = 0;
    l = NULL;
    r = NULL;
  }
};

template <class T>
cartesian_tree<T> * merge (cartesian_tree<T> *u, cartesian_tree<T> *v)
{
  if (u == NULL)
    return v;

  if (v == NULL)
    return u;

  if (u->y >= v->y)
  {
    u->r = merge (u->r, v);
    u->count = (u->l != NULL ? u->l->count : 0) + (u->r != NULL ? u->r->count : 0) + 1;
    return u;
  }
  else
  {
    v->l = merge (u, v->l);
    v->count = (v->l != NULL ? v->l->count : 0) + (v->r != NULL ? v->r->count : 0) + 1;
    return v;
  }
}

template <class T>
cartesian_tree<T> split (cartesian_tree<T> *u, int key)
{
  cartesian_tree<T> res, tmp;

  res.l = res.r = NULL;

  if (u == NULL)
    return res;

  if (u->key >= key)
  {
    tmp = split (u->l, key);
    u->l = tmp.r;
    u->count = (u->l != NULL ? u->l->count : 0) + (u->r != NULL ? u->r->count : 0) + 1;
    res.l = tmp.l, res.r = u;
  }
  else
  {
    tmp = split (u->r, key);
    u->r = tmp.l;
    u->count = (u->l != NULL ? u->l->count : 0) + (u->r != NULL ? u->r->count : 0) + 1;
    res.r = tmp.r, res.l = u;
  }

  return res;
}

template <class T>
cartesian_tree<T>* del (cartesian_tree<T> *u, cartesian_tree<T> *p, cartesian_tree<T> *node, T key)
{
  if (u == NULL)
    return node;

  if (u->key == key)
  {
    cartesian_tree<T> *d;
    if (p == NULL)
      d = node, node = merge (node->l, node->r);
    else
    {
      if (p->r == u)
        d = p->r, p->r = merge(u->l, u->r);
      else
        d = p->l, p->l = merge(u->l, u->r);
    }
//    free(d);!!!
    return node;
  }

  if (u->key > key)
    return del(u->l, u, node, key);
  else
    return del(u->r, u, node, key);
  u->count = (u->l != NULL ? u->l->count : 0) + (u->r != NULL ? u->r->count : 0) + 1;
}

template <class T>
cartesian_tree<T>* add (cartesian_tree<T> *u, cartesian_tree<T> *v)
{
  if (u == NULL)
    return v;

  if (u->y > v->y)
  {
    if (u->key < v->key)
    {
      u->r = add(u->r, v);
      u->count = (u->l != NULL ? u->l->count : 0ll) + (u->r != NULL ? u->r->count : 0) + 1;
    }
    else
    {
      u->l = add(u->l, v);
      u->count = (u->l != NULL ? u->l->count : 0ll) + (u->r != NULL ? u->r->count : 0) + 1;
    }
    return u;
  }
  else
  {
    cartesian_tree<T> tmp;
    tmp = split (u, v->key);
    v->l = tmp.l, v->r = tmp.r;
    v->count = (v->l != NULL ? v->l->count : 0) + (v->r != NULL ? v->r->count : 0) + v->key;
    return v;
  }

  return NULL;
}

template <class T>
uint greater_count (cartesian_tree<T>* u, T key)
{
  if (u == NULL)
    return 0;

  uint res = 0;
  
  if (u->key >= key)
  {
    if (u->r != NULL)
      res += u->r->count;
    return res + 1 + greater_count(u->l, key);
  }
  else
    return greater_count(u->r, key);
}

template <class T>
T get_min (cartesian_tree<T>* v)
{
  if (v->l != NULL)
    return get_min(v->l);
  return v->key;
}

template <class T>
void clear (cartesian_tree<T> *u)
{
  if (u == NULL)
    return;
  clear(u->l), clear(u->r);
//  free(u);!!!
}

template <class T>
class myset
{
public:
  cartesian_tree<T> *node;

  myset()
  {
    node = NULL;
  }

  void insert (int k)
  {
    cartesian_tree<T> *v = new cartesian_tree<T>(k);
    node = add (node, v);
  }

  void erase (int k)
  {
    node = del (node, NULL, node, k);
  }

  uint greater_count (T k)
  {
    return ::greater_count (node, k);
  }

  T get_min ()
  {
    return ::get_min(node);
  }
};

void test (int STEP_COUNT, int ELEM_COUNT)
{
  for (int i = 0; i < STEP_COUNT; i++)
  {
    myset <int> s;
    for (int j = 0; j < ELEM_COUNT; j++)   
      s.insert(rand() + j);
  }
} 

int main (int argc, char *argv[])
{
	assert(argc == 3);
	int STEP_COUNT, ELEM_COUNT;

	sscanf (argv[1], "%d", &STEP_COUNT);
	sscanf (argv[2], "%d", &ELEM_COUNT);

	test(STEP_COUNT, ELEM_COUNT);

	return 0;
}
